#! /usr/bin/env python
# -*- coding: utf-8 -*-

import urllib
import re
import os
import sys
import time

import FileHostProtoType

class muitem(FileHostProtoType.HostItem):
    def __init__(self, name, code, type, link='', encrypt_name='', server_name=''):
        FileHostProtoType.HostItem.__init__(self, name, type, code, link, encrypt_name, server_name)
        if self.type == 'file':
            self.link = "http://www.megaupload.com/?d=%s" % self.id
        if self.type == 'folder':
            self.link = "http://www.megaupload.com/?f=%s" % self.id

    
class megaupload(FileHostProtoType.FileHostProcess):            
    def __init__(self, user, pwd, fhout=sys.stdout, fherr=sys.stderr):
        FileHostProtoType.FileHostProcess.__init__(self, fhout, fherr)
        self.hostname = "MegaUpload" 
        self._opener = None
        self._user = user
        self._pwd = pwd
        self.islogin = False
       
    def login(self):
        self.fherr.write('Megaupload has gone.')
        return False
        
        if self.islogin:
            return True
        if self._opener is not None:
            return False
        self.fherr.write('login to Megaupload %s/%s...' % (self._user,'*'*len(self._pwd)))
        loginData = {'login' : '1', 
                     'username' : self._user, 
                     'password' : self._pwd,
                     'redir=1' : '1'
                     }
        loginresult =  self.loginFileHost(
                    "http://www.megaupload.com/?c=login", 
                    loginData
                    )
        # you always see you username at the top of the page, if login successfully.
        if self._user.lower() not in loginresult.lower():
            self.fherr.write("User %s Failed to Login MegaUpload." % self._user)
            return False
        self.fherr.write("User %s logined." % self._user)
        self.islogin = True
        return True
    
    def generateUrl(self, nu=500, ty=0, pa=1, so='name', di='asc', sq=''):
        url = "http://www.megaupload.com/?c=filemanager&ajax=1&"
        params = []
        rnd = int(time.time()*1000)
        params.append(('r',rnd))
        params.append(('nu',nu))
        params.append(('ty',ty))
        params.append(('pa',pa))
        params.append(('so',so))
        params.append(('di',di))
        if not sq:
            params.append(('sq',sq))
        url += urllib.urlencode(params)
        return url
    
    def translateUnicode(self, str=''):
        if not str:
            return str        
        uStr= ''
        try:
            exec 'uStr=u"%s"' % str
        except:
            self.fherr.write('%s is not a unicode string.' % str)
            return str
        return uStr
        
    def getFileList(self):
        return self.search(typefilter=1)
    
    def getFolderList(self):
        return self.search(typefilter=2)
    
    def search(self, keyword="", typefilter=0):
        '''
        open the filelist page according to opener with cookies
        params:
        keyword: some word to search
        typefilter: 0(file and folder),1(file),2(folder)
        '''
        self.fherr.write('Search...')
        filelinks = []
        showPerPage = 500
        currentPage = 1
        pageCount = 1
        while(currentPage <= pageCount):   
            megaUploadExecPage = self.generateUrl(
                                nu=showPerPage, 
                                pa=currentPage, 
                                sq=keyword, 
                                ty = typefilter
                                )
            retData = self.post_request(megaUploadExecPage)
            retData = retData.strip().replace(r'\/', '/')
            retData = retData.strip().replace('null', '"null"')
            messageDict = {}
            try:
                exec('messageDict=' + retData)
            except:
                self.fherr.write("Failed to Get file list.")
                continue
            pageCount = (int(messageDict.get('totalfiles', '0')) +\
                            int(messageDict.get('totalfolders', '0')))/showPerPage + 1
            currentPage = currentPage + 1
            if messageDict['records'] == 'null':
                continue
            for r in messageDict['records']:
                item = muitem(self.translateUnicode(r['name']), r['id'], r['type'])
                filelinks.append(item)
        filelinks.sort()
        return filelinks
    
    def find(self, filenames=None, filelist=None, keyword="", filter=0):
        foundItems = []
        if not filenames:
            return foundItems
        files = []
        if filelist is None:
            files = self.search(keyword=keyword, typefilter=filter)
        else:
            files.extend(filelist)            
        lowerFileList = [f.name.lower() for f in files]
        toDelete = []
        for f in filenames:
            index = -1
            try:
                index = lowerFileList.index(os.path.basename(f).lower())
            except:
                index = -1
            if index == -1:
                continue
            foundItems.append(files[index])
            toDelete.append(f)
        for d in toDelete:
            filenames.remove(d)
        foundItems.sort()
        return foundItems
    
    def findFolder(self, foldername):
        findfolder = self.find(filenames=[foldername], filter=2)
        if len(findfolder):
            self.fherr.write('Found folder %s' % foldername)
            return findfolder[0]
        return None
    
    def createFolder(self, foldername):
        foundFolder = self.findFolder(foldername)
        if foundFolder is None:
            return self._newFolder(foldername)
        return foundFolder
        
    def _newFolder(self, foldername):         
        self.fherr.write('Creating Folder...%s' % foldername)
        megaUploadExecPage = self.generateUrl(nu=1)
        post_params = []
        post_params.append(('action', 'createfolder'))
        post_params.append(('name', foldername))
        retData = self.post_request(megaUploadExecPage, post_params)
        retData = retData.strip().replace(r'\/', '/')
        #messageDict = {}
        #try:
        #    exec('messageDict=' + retData)
        #except:
        #    self.fherr.write("Failed to Create Folder")
        #    return None        
        #message = self.translateUnicode(messageDict['actionmessage'])
        #self.fherr.write(message)
        #code = message[message.find('?f=') + 3 : message.rfind('</b>')]
        item = self.findFolder(foldername)
        return item
    
    def moveto(self, items, folder):
        self.fherr.write('Copying...')
        megaUploadExecPage = self.generateUrl(nu=1) 
        post_params = []    
        post_params.append(('action', 'copy'))
        post_params.append(('folderid', folder.id))
        ids = ''
        for i in items:
            if i.type == 'folder':
                self.fherr.write("%s is a folder, you can't copy it to some other folder." % i.name)
                continue
            ids += 'file_%s;' % i.id
        if ids == '':
            return
        post_params.append(('copyids', ids))  
        retData = self.post_request(megaUploadExecPage, post_params)
        retData = retData.strip().replace(r'\/','/')
        messageDict = {}
        try:
            exec('messageDict=' + retData)
        except:
            self.fherr.write("Failed to Create Folder")
            return
        self.fherr.write(self.translateUnicode(messageDict['actionmessage']))

    def upload_web(self, file, progressLog=None, other_args=None):
        return self.upload_web_local(file, progressLog, other_args)

    def upload_web_local(self, file, progressLog=None, other_args=None):
        
        basefilename = os.path.basename(file)            
        #get index.html, find the upload link
        #be careful: params pass to pycurl should be utf8!  
        indexpage = self.post_request("http://www.megaupload.com/multiupload/").encode('utf8','ignore')                  
        reUploadLink = re.compile("(?P<uploadlink>http://www\d+.megaupload\.com/upload_done\.php\?UPLOAD_IDENTIFIER=(?P<identifier>\d+))")
        s = reUploadLink.search(indexpage)
        if s is None:
            self.fherr.write("Fail to Get Upload Link for %s, Wait for 1min and Retry..." % file)
            return
        
        uploadlink = s.group('uploadlink')
        identifier = s.group('identifier')
        
        #upload
        self.fherr.write("Uploading...%s " % file)
        message = u'airu-upload'
        if other_args:
            message = other_args.get('message',u'airu-upload')
        message = message.encode('utf8', 'ignore')
        
        callback = None
        if progressLog is not None:
            callback = progressLog.write
        data = {
                'file':open(file,'rb'),
                'UPLOAD_IDENTIFIER':identifier,
                'sessionid':identifier,
                'message':message,
                }

        linkinfo = self.post_file(uploadlink, \
                                  data, \
                                  self.get_cookies(), \
                                  callback=callback)

        if linkinfo is None:
            self.fherr.write("UploadTask(%s) was Stop by user. " % file)
            return
        
        reMUFileLink = re.compile("http://www\.megaupload\.com/\?d=(?P<code>\w+)",re.S|re.I)      
        s = reMUFileLink.search(linkinfo)
        if s is None:
            self.fherr.write("Fail to get file link for %s from upload-log, Wait for 1min and Retry..." % file)
            return
        
        code = s.group('code')
        item = muitem(basefilename, code, 'file', '', self.rename_func(file))
        self.fherr.write(item.format())
        self.newupload.append(item)
        self.fherr.write("#Uploaded...%s#" % file)        
        return item

if __name__ == "__main__":
    pass
